package com.stottlerhenke.simbionic.editor.gui;

import java.awt.Point;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.TreeMap;
import java.util.regex.Pattern;

import com.stottlerhenke.simbionic.editor.SB_CancelException;
import com.stottlerhenke.simbionic.editor.SB_ErrorInfo;
import com.stottlerhenke.simbionic.editor.gui.api.I_CompileValidator;

public class SB_ConnectorComposite extends SB_DrawableComposite
{
    private static final long serialVersionUID = 2302585093L + 1004;

    public boolean add(SB_Drawable drawable)
    {
      SB_Connector connector = (SB_Connector) drawable;
      connector.setId(count());
      return super.add(connector);
    }

    public SB_Connector containsPoint_StartEnd(Point point, SB_DragType dragType)
    {
        SB_Connector connector;
        int size = _drawables.size();
	for (int i = size - 1; i >= 0; --i)
	{
            connector = (SB_Connector) _drawables.get(i);
                if (connector.getEndRect().contains(point))
		{
                    dragType.type = SB_DragType.kDragEndPoint;
                    return connector;
		}
		else if (connector.getStartRect().contains(point))
		{
                    dragType.type = SB_DragType.kDragStartPoint;
                    return connector;
		}
	}
	return null;
    }

    protected SB_Connector containsPoint_End(Point point)
    {
        SB_Connector connector;
        int size = _drawables.size();
	for (int i = size - 1; i >= 0; --i)
	{
            connector = (SB_Connector) _drawables.get(i);
                if (connector.getEndRect().contains(point))
                    return connector;
	}
	return null;
    }

    protected SB_Connector containsPoint_Label(Point point)
    {
        SB_Connector connector;
        int size = _drawables.size();
	for (int i = size - 1; i >= 0; --i)
	{
            connector = (SB_Connector) _drawables.get(i);
                if (connector.containsPoint_Label(point) != null)
                    return connector;
	}
	return null;
    }

    protected void updatePoints()
    {
        int size = _drawables.size();
        for (int i = 0; i < size; ++i)
            ((SB_Connector) _drawables.get(i)).updatePoints();
    }

    public void updateTwoWay()
    {
      int size = _drawables.size();
      for (int i = 0; i < size; ++i)
          ((SB_Connector) _drawables.get(i)).updateTwoWay();
      updatePoints();
    }

    protected void resetIds()
    {
      int size = _drawables.size();
      for (int i = 0; i < size; ++i)
        ((SB_Connector) _drawables.get(i)).setId(i);
    }

    protected void compileSIM(BufferedWriter out, SB_Polymorphism poly, SB_ErrorInfo errorInfo, I_CompileValidator validator)
    {
      try
      {
        // transitions
        int size = count();
        out.write("\t\t\t\tTransitions " + size);
        out.newLine();
        TreeMap map = new TreeMap();
        mapById(map);
        for (int i = 0; i < size; ++i)
        {
          SB_Connector connector = (SB_Connector) map.get(new Integer(i));
          connector.compileSIM(out, poly, errorInfo);
          validator.validateConnector(connector,poly);
        }
        map.clear();
      }
      catch (IOException exception)
      {
        System.err.println("i/o exception");
      }
    }

    protected boolean isUnreachable(SB_Element element)
    {
      int size = _drawables.size();
      for (int i = 0; i < size; ++i)
      {
        if (((SB_Connector) _drawables.get(i)).getEndElement() == element)
          return false;
      }
      return true;
    }

    protected void exportXML(BufferedWriter out) throws IOException
    {
      SB_Connector connector;
      int size = _drawables.size();
      for (int i = 0; i < size; ++i)
      {
        connector = (SB_Connector)  _drawables.get(i);
        if (connector.getStartElement() == null)
        {
          out.write("\t\t\t\t\t\t<start>");
          out.newLine();
          out.write("\t\t\t\t\t\t\t<id>-1</id>");
          out.newLine();
          out.write("\t\t\t\t\t\t\t<x>" + connector.getStartPoint().x + "</x>");
          out.newLine();
          out.write("\t\t\t\t\t\t\t<y>" + connector.getStartPoint().y + "</y>");
          out.newLine();
          out.write("\t\t\t\t\t\t\t<connector>");
          out.newLine();
          connector.exportXML(out);
          out.write("\t\t\t\t\t\t\t</connector>");
          out.newLine();
          out.write("\t\t\t\t\t\t</start>");
          out.newLine();
        }
      }
      out.write("\t\t\t\t\t</connectors>");
      out.newLine();
    }

    protected int findOccurrences(Pattern pattern, String strReplace, SB_Polymorphism poly) throws SB_CancelException
    {
      int total = 0;
      SB_Connector connector;
      int size = _drawables.size();
      for (int i = 0; i < size; ++i)
      {
        connector = (SB_Connector) _drawables.get(i);
        total += connector.findOccurrences(pattern, strReplace, poly);
      }
      return total;
    }
}
